package com.txw.javaCore.server.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import com.txw.javaCore.api.enums.Constant;
import com.txw.javaCore.model.entity.Blog;
import com.txw.javaCore.model.entity.Course;
import com.txw.javaCore.model.entity.IndexImg;
import com.txw.javaCore.model.entity.Link;
import com.txw.javaCore.model.mapper.BlogMapper;
import com.txw.javaCore.model.mapper.CourseMapper;
import com.txw.javaCore.model.mapper.IndexImgMapper;
import com.txw.javaCore.model.mapper.LinkMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @PROJECT_NAME: JavaCoreB2
 * @DESCRIPTION:
 * @Author: 涂玄武
 * @DATE: 2021/2/3 10:55
 */
@Service
public class IndexDataService {

    private static final Logger log= LoggerFactory.getLogger(IndexDataService.class);

    //队列中可以容纳/等待被处理的任务数量的阈值的设定
    private static final BlockingQueue BLOCKING_QUEUE=new ArrayBlockingQueue(30);

    //超过了能处理任务的最大线程数的任务的处理策略
    private static final ThreadPoolExecutor.CallerRunsPolicy POLICY=new ThreadPoolExecutor.CallerRunsPolicy();

    //核心线程数;最大线程数;当线程数>核心线程数时那些空闲线程在关闭之前等待新任务到来的最大等待时间;任务队列;拒绝策略
    private static final ThreadPoolExecutor EXECUTOR=new ThreadPoolExecutor(4,8,10000, TimeUnit.SECONDS,BLOCKING_QUEUE,POLICY);

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private IndexImgMapper imgMapper;

    @Autowired
    private LinkMapper linkMapper;

    /**
     * 获取首页数据 - 首页数据由各大功能模块组成（各大模块的数据的获取是互不干扰、独立的）
     * 轮播图、最新课程、最新博客、友情链接
     * @return
     * @throws Exception
     */
    public Map<String,Object> getIndexDataV1() throws Exception{
        Map<String,Object> map= Maps.newHashMap();

        //轮播图
        PageHelper.startPage(Constant.indexPageNo,Constant.indexPageImgSize);
        map.put("indexImgs",new PageInfo<>(imgMapper.selectIndexImgs()).getList());

        //课程模块
        PageHelper.startPage(Constant.indexPageNo,Constant.indexPageSize);
        map.put("indexCourses",new PageInfo<>(courseMapper.selectIndexCourses()).getList());

        //博客模块
        PageHelper.startPage(Constant.indexPageNo,Constant.indexPageSize);
        map.put("indexBlogs",new PageInfo<>(blogMapper.selectIndexBlog()).getList());

        //友情链接
        PageHelper.startPage(Constant.indexPageNo,Constant.indexPageLinkSize);
        map.put("indexLinks",new PageInfo<>(linkMapper.selectIndexLinks()).getList());

        return map;
    }

    /**
     * 获取首页数据 - 首页数据由各大数据模块组成，要求各大数据模块的获取采用异步的方式取得（即各大模块的数据的获取是互不干扰、独立的）
     * 多线程+FutureTask(Functional机制)
     * 因为线程执行后不能同步获取执行结果，因此需要利用FutureTask来获取
     * @return
     * @throws Exception
     */
    public Map<String,Object> getIndexDataV2() throws Exception{
        Map<String,Object> map= Maps.newHashMap();

        //轮播图
        Callable<List<IndexImg>> imgCallable = () -> {
            PageHelper.startPage(Constant.indexPageNo,Constant.indexPageImgSize);
            return new PageInfo<>(imgMapper.selectIndexImgs()).getList();
        };
        FutureTask<List<IndexImg>> imgTask = new FutureTask<>(imgCallable);

        //课程模块
        Callable<List<Course>> courseCallable= () -> {
            PageHelper.startPage(Constant.indexPageNo,Constant.indexPageSize);
            return new PageInfo<>(courseMapper.selectIndexCourses()).getList();
        };
        FutureTask<List<Course>> courseTask=new FutureTask<>(courseCallable);

        //博客模块
        Callable<List<Blog>> blogCallable= () -> {
            PageHelper.startPage(Constant.indexPageNo,Constant.indexPageSize);
            return new PageInfo<>(blogMapper.selectIndexBlog()).getList();
        };
        FutureTask<List<Blog>> blogTask=new FutureTask<>(blogCallable);

        //友情链接
        Callable<List<Link>> linkCallable= () -> {
            PageHelper.startPage(Constant.indexPageNo,Constant.indexPageLinkSize);
            return new PageInfo<>(linkMapper.selectIndexLinks()).getList();
        };
        FutureTask<List<Link>> linkTask=new FutureTask<>(linkCallable);

        //多条路-多个线程并发、并行执行获取数据
        EXECUTOR.submit(imgTask);
        EXECUTOR.submit(courseTask);
        EXECUTOR.submit(blogTask);
        EXECUTOR.submit(linkTask);

        map.put("indexImgs",imgTask.get());
        map.put("indexCourses",courseTask.get());
        map.put("indexBlogs",blogTask.get());
        map.put("indexLinks",linkTask.get());
        return map;
    }
}
